﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Meraz.Core.Model;
using Meraz.Core.Repositories;
using Ninject;
using System.Diagnostics;
using System.Configuration;
using System.IO;
using Meraz.Core.Parsers;
using Meraz.Core.Helpers;

namespace Meraz.Core.Managers
{
    public interface IFacebookManager
    {
        List<FacebookTopicBoard> GetBoards();
        FacebookTopicBoard GetBoard(long boardID);
        FacebookTopic GetTopic(long boardID, int topicID);
        FacebookTopicPost GetPost(long boardID, int topicID, int postID);
        void LoadTopic(FacebookTopic topic);
        void Save(FacebookTopic topic);
        void Save(FacebookTopicPost post);
        void Save(FacebookTopicPostLink link);
        void SavePostLinks(FacebookTopicPost post);
        List<string> GetGenres();
        List<string> GetSubjects();
        List<string> GetSources();
        void ParseTopic(string content, long boardID, int topicID);
    }
    public class FacebookManager : IFacebookManager
    {
        #region Properties
        [Inject]
        public IFacebookTopicBoardRepository FacebookTopicBoardRepository { get; set; }
        [Inject]
        public IFacebookTopicRepository FacebookTopicRepository { get; set; }
        [Inject]
        public IFacebookTopicPostRepository FacebookTopicPostRepository { get; set; }
        [Inject]
        public IFacebookTopicPostLinkRepository FacebookTopicPostLinkRepository { get; set; }
        [Inject]
        public IFacebookBoardParser FacebookBoardParser { get; set; }
        [Inject]
        public MyWebClient Client { get; set; }
        #endregion

        public List<FacebookTopicBoard> GetBoards()
        {
            return FacebookTopicBoardRepository.All();
        }
        public FacebookTopicBoard GetBoard(long boardID)
        {
            FacebookTopicBoard result = FacebookTopicBoardRepository.GetById(boardID);
            if (result != null)
                result.Topics = FacebookTopicRepository.GetByBoardId(boardID);
            return result;
        }
        public FacebookTopic GetTopic(long boardID, int topicID)
        {
            FacebookTopic result = FacebookTopicRepository.GetById(boardID, topicID);

            //Determine if this is a new topic, if so, must get posts from facebook
            if (result.Status.Equals(StatusType.New.ToString()))
            {
                string content = Client.DownloadString(result.Url);
                if (Client.ResponseUri.AbsolutePath.Contains("browser.php")) throw new ApplicationException("Unable to load Topic page!");
                result.Status = StatusType.Active.ToString();
                FacebookBoardParser.ParseTopic(content, result);
                result.Poster = result.Posts[0].Poster;
                Save(result);
            }
            else
            {
                result.Posts = FacebookTopicPostRepository.GetTopicPosts(boardID, topicID);
                //maybe the topic is not new but the post is back to new, parse links
                foreach (FacebookTopicPost post in result.Posts)
                {
                    if (post.Status.Equals(StatusType.New.ToString())){
                        FacebookBoardParser.ParsePost(post.Text, post);
                        post.Status = StatusType.Pending.ToString();
                        Save(post);
                    }
                    //we only want the first post of the topic and its links, so clear collections
                    post.Links.Clear();
                }
                
                foreach (FacebookTopicPostLink link in FacebookTopicPostLinkRepository.GetTopicLinks(boardID, topicID))
                {
                    FacebookTopicPost post = result.Posts.FirstOrDefault(f => f.TopicID == link.TopicID && f.ID == link.PostID);
                    if (post == null) continue;
                    post.Links.Add(link);
                }
            }
            return result;
        }
        public FacebookTopicPost GetPost(long boardID, int topicID, int postID)
        {

            FacebookTopicPost result = FacebookTopicPostRepository.GetById(boardID, topicID, postID);
            result.Links = FacebookTopicPostLinkRepository.GetTopicPostLinks(boardID, topicID, postID);
            return result;
        }
        public void Save(FacebookTopic topic)
        {
            foreach (FacebookTopicPost post in topic.Posts)
            {
                FacebookTopicPost existingPost = FacebookTopicPostRepository.GetById(topic.BoardID, topic.ID, post.ID);
                if (existingPost == null)
                {
                    FacebookTopicPostRepository.Save(post);
                }
                else
                {
                    existingPost.Genre = post.Genre;
                    existingPost.Poster = post.Poster;
                    existingPost.Subject = post.Subject;
                    existingPost.Status = StatusType.Active.ToString();
                    FacebookTopicPostRepository.Save(existingPost);
                }
                FacebookTopicPostLinkRepository.Delete(topic.BoardID, topic.ID, post.ID);
                foreach (FacebookTopicPostLink link in post.Links)
                {
                    FacebookTopicPostLinkRepository.Save(link);
                }
            }
            FacebookTopic existing = FacebookTopicRepository.GetById(topic.BoardID, topic.ID);
            existing.Poster = topic.Poster;
            existing.TotalPosts = FacebookTopicPostRepository.GetTotalPosts(topic.BoardID, topic.ID);
            existing.UniqueUsers = FacebookTopicPostRepository.GetUniqueUserCount(topic.BoardID, topic.ID);
            FacebookTopicRepository.Save(topic);
        }
        public void Save(FacebookTopicPostLink link)
        {
            FacebookTopicPostLink existingLink = FacebookTopicPostLinkRepository.GetById(link.BoardID, link.TopicID, link.PostID, link.ID);
            if (existingLink == null)
                FacebookTopicPostLinkRepository.Save(link);
            else
            {
                existingLink.ActualUrl = link.ActualUrl;
                existingLink.Source = link.Source;
                existingLink.Level1 = link.Level1;
                existingLink.Level2 = link.Level2;
                existingLink.Broadcast = (string.IsNullOrWhiteSpace(link.Broadcast)) ? "" : link.Broadcast;
                existingLink.Citation = (string.IsNullOrWhiteSpace(link.Citation)) ? "" : link.Citation;
                existingLink.Tone = link.Tone;
                FacebookTopicPostLinkRepository.Save(existingLink);
            }
        }
        public void SavePostLinks(FacebookTopicPost post)
        {
            FacebookTopicPost existing = GetPost(post.BoardID, post.TopicID, post.ID);
            existing.Status = StatusType.Active.ToString();
            existing.WordCount = post.WordCount;

            FacebookTopicPostRepository.Save(existing);

            foreach (FacebookTopicPostLink existingLink in existing.Links)
            {
                FacebookTopicPostLink link = post.Links.SingleOrDefault(single => single.Equals(existingLink));
                existingLink.ActualUrl = (string.IsNullOrWhiteSpace(link.ActualUrl))? "" : link.ActualUrl;
                existingLink.Source = (string.IsNullOrWhiteSpace(link.Source)) ? "" : link.Source;
                existingLink.Level1 = (string.IsNullOrWhiteSpace(link.Level1)) ? "" : link.Level1;
                existingLink.Broadcast = (string.IsNullOrWhiteSpace(link.Broadcast)) ? "" : link.Broadcast;
                existingLink.Citation = (string.IsNullOrWhiteSpace(link.Citation)) ? "" : link.Citation;
                existingLink.Level2 = (string.IsNullOrWhiteSpace(link.Level2)) ? "" : link.Level2;
                existingLink.Tone = (string.IsNullOrWhiteSpace(link.Tone)) ? "" : link.Tone;
                existingLink.Status = StatusType.Active.ToString();
                existingLink.Old = (string.IsNullOrWhiteSpace(link.Old)) ? "" : link.Old;
                FacebookTopicPostLinkRepository.Save(existingLink);
            }
        }
        public void LoadTopic(FacebookTopic topic)
        {
            FacebookTopic existing = FacebookTopicRepository.GetById(topic.BoardID, topic.ID);
            existing.Poster = topic.Posts[0].Poster;
            existing.Status = StatusType.Active.ToString();
            existing.TotalPosts = topic.TotalPosts;
            existing.UniqueUsers = topic.UniqueUsers;
            FacebookTopicRepository.Save(existing);
            foreach (FacebookTopicPost post in topic.Posts)
            {
                post.Genre = "";
                post.Subject = "";
                post.Status = StatusType.Active.ToString();
                FacebookBoardParser.ParsePost(post.Text, post);
                FacebookTopicPostRepository.Save(post);
                FacebookTopicPostLinkRepository.Delete(post.BoardID, post.TopicID, post.ID);
                foreach (FacebookTopicPostLink link in post.Links)
                {
                    FacebookTopicPostLinkRepository.Save(link);
                }
            }
        }
        public void ParseTopic(string content, long boardID, int topicID)
        {

        }
        public void Save(FacebookTopicPost post)
        {
            FacebookTopicPostRepository.Save(post);
            FacebookTopicPostLinkRepository.Delete(post.BoardID, post.TopicID, post.ID);
            foreach (FacebookTopicPostLink link in post.Links)
            {
                FacebookTopicPostLinkRepository.Save(link);
            }
        }
        public List<string> GetGenres()
        {
            return FacebookTopicPostRepository.GetGenres();
        }
        public List<string> GetSubjects()
        {
            return FacebookTopicPostRepository.GetSubjects();
        }
        public List<string> GetSources()
        {
            return FacebookTopicPostLinkRepository.GetSources();
        }


    }
}
